package org.zhaolei.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.zhaolei.constant.CacheKey;
import org.zhaolei.enums.BizCodeEnum;
import org.zhaolei.enums.SendCodeEnum;
import org.zhaolei.component.MailService;
import org.zhaolei.service.NotifyService;
import org.zhaolei.util.CheckUtil;
import org.zhaolei.util.CommonUtil;
import org.zhaolei.util.JsonData;

import java.util.concurrent.TimeUnit;

/**
 * 这里实现发送邮件验证码的具体逻辑
 * 前置：判断是否重复发送
 * 1. 存储验证码到缓存
 * 2. 发送邮箱验证码
 * 后置： 存储发送记录
 */
@Service
@Slf4j
public class NotifyServiceImpl implements NotifyService {

    @Autowired
    private MailService mailService;

    @Autowired
    private RedisTemplate redisTemplate;

    private static final String SUBJECT = "小迪课堂验证码";

    private static final String CONTENT = "您的验证码是：%s，有效时间是60秒，不要告诉他人哦！！";

    /**
     * 邮箱验证码10分钟内有效，验证码最多每60秒可以发送一次
     */
    private static final int CODE_EXPIRED = 60 * 1000 * 10;

    @Override
    public JsonData sendCode(SendCodeEnum sendCodeEnum, String to) {

        //后面两个量会填入第一个参数的%s中，这是邮箱验证码的key
        String cacheKey = String.format(CacheKey.CHECK_CODE_KEY, sendCodeEnum.name(),to);

        String cacheValue = (String)redisTemplate.opsForValue().get(cacheKey);

        //如果不为空，或者60秒内发送过了
        if(StringUtils.isNotBlank(cacheValue)) {
            long ttl = Long.parseLong(cacheValue.split("_")[1]);
            //当前时间戳-Redis中验证码发送的时间戳，如果小于60秒，则不给重复发送
            if (CommonUtil.getCurrentTimestamp() - ttl < 1000 * 60) {
                log.info("重复发送验证码，时间间隔:{} 秒", (CommonUtil.getCurrentTimestamp() - ttl) / 1000);
                return JsonData.buildResult(BizCodeEnum.CODE_LIMITED);
            }
        }
        //拼接验证码，用时间戳拼接验证码
        String code = CommonUtil.getRandomCode(6);
        String value = code + "_" + CommonUtil.getCurrentTimestamp();
        //存储到redis中
        redisTemplate.opsForValue().set(cacheKey, value, CODE_EXPIRED, TimeUnit.MILLISECONDS);

        //如果为空，或者不为空但上次发送超过60秒了，则进入下面的逻辑

        if (CheckUtil.isEmail(to)) {
            //这里直接发送邮箱验证码了，没有加入到redis，所以要上移，加入到redis
//            String code = CommonUtil.getRandomCode(6);
            mailService.sendMail(to, SUBJECT, String.format(CONTENT, code));
            return JsonData.buildSuccess();
        } else if (CheckUtil.isPhone(to)) {
            //发送短信验证码
        }

        return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
    }

    @Override
    public boolean checkCode(SendCodeEnum sendCodeEnum, String to, String code) {
        //构造缓存中的key
        String cacheKey = String.format(CacheKey.CHECK_CODE_KEY, sendCodeEnum.name(),to);
        //从redis中获取验证码
        String cacheValue = (String)redisTemplate.opsForValue().get(cacheKey);
        if(StringUtils.isNotBlank(cacheValue)) {
            String code_redis = cacheValue.split("_")[0];
            if (code.equals(code_redis)) {
                //删除验证码
                redisTemplate.delete(cacheKey);
                return true;
            }
        }
        return false;
    }
}
